package com.henghai.zhenxuan.pay.newpay;

import java.util.Map;

import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.PayTask;
import com.henghai.zhenxuan.R;

import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

/**
 *  重要说明：
 *
 *  本 Demo 只是为了方便直接向商户展示支付宝的整个支付流程，所以将加签过程直接放在客户端完成
 *  （包括 OrderInfoUtil2_0_HK 和 OrderInfoUtil2_0）。
 *
 *  在真实 App 中，私钥（如 RSA_PRIVATE 等）数据严禁放在客户端，同时加签过程务必要放在服务端完成，
 *  否则可能造成商户私密数据泄露或被盗用，造成不必要的资金损失，面临各种安全风险。
 *
 *  Warning:
 *
 *  For demonstration purpose, the assembling and signing of the request parameters are done on
 *  the client side in this demo application.
 *
 *  However, in practice, both assembling and signing must be carried out on the server side.
 */
public class PayDemoActivity extends AppCompatActivity {

    /**
     * 用于支付宝支付业务的入参 app_id。
     */
    public static final String APPID = "2021004166677007";

    /**
     * 用于支付宝账户登录授权业务的入参 pid。
     */
    public static final String PID = "2088842919747779";

    /**
     * 用于支付宝账户登录授权业务的入参 target_id。
     */
    public static final String TARGET_ID = "zhelishitarget_id";

    /**
     *  pkcs8 格式的商户私钥。
     *
     * 	如下私钥，RSA2_PRIVATE 或者 RSA_PRIVATE 只需要填入一个，如果两个都设置了，本 Demo 将优先
     * 	使用 RSA2_PRIVATE。RSA2_PRIVATE 可以保证商户交易在更加安全的环境下进行，建议商户使用
     * 	RSA2_PRIVATE。
     *
     * 	建议使用支付宝提供的公私钥生成工具生成和获取 RSA2_PRIVATE。
     * 	工具地址：https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=106097&docType=1
     */
    public static final String RSA2_PRIVATE = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDLPtmSf+Rz/anXzIeQsuvPvtWTNAzwq2qxWyQoCuvnVS5pgexaRqmLyKUA1Esyw0UoghOKCF9yfobMqB/a16QjLPe52rJeLNFj+8eWTd3Bgw5OeD2xGR8NP3cUoYxX9A4CasF7aq72mXAyZaqJZfj7koknld5h97ethnxz1Xg8+SPX483kIT5bNLgdjDZRxEPngXJYPtdUJf4KMLuzS0NjYe9n3Gde1XOt6pdlotSOnwsmQBuyP7xIoB6xPryL3/w+AvHy1vAScQau1ljXkbVHW1Rr1LYwXXz8BjBX5QYvNl6VzAIbTQEJOdWL1ECE4Lv6lNk+OJyAZBIYz5f3Soa5AgMBAAECggEATCqRfsVO5+j37VdItoFWvdPWVgP7lXWn1i9BrX/qSBcz/XYjDPHOOARJUbY9OBjVogidKe1ZV57zBV88ENcfO89uRsgecAx7q+x/L2Se5hYnFmEZPXUcnepaxfCEl7FuTpmTSJ0CVIfL9BcFgdglJqITpDIV1MDwpKbxnLczCCXqVpHdHrUO5ILqUWV45XcM6M2Jy4WfO8gImsYjx2SZPoYS1qcURS5ImLBIgk6REbUYCwtiANyd9szWLWKO0osT5h9IbORgEAZXXm2V4OW8T3ESHL5i2QHPaCcnn6wXmvD3bPD9vE0A+mMwwwP+iKROlZdWk2mzVJBHdEkurRTIAQKBgQD0n0TXjBJhVEDqR2owAMw9MQiUBqpr4usLr+BPABCw/g9kZNfE1swi9vbj20aUyg2clwJ1MRnZs2bG+7KxZLDKtaG409kd+qeGWle1FQemX5ZRa55TpdiAWLCl0KL96Tp0kR3rPoLoKarvtSchjvnq+rLoTvRp19plmLVEqwkSSQKBgQDUsugjXgoNSs+gQwoRiwHXWaLeZBkPiNYrMaJTivLaE5wTooTFbSixNHDv4tggvqquGXY3zgu2r3Y/QOFOJL8Nqd5R1/qEVG0ykCYJgjWy9U5AZZtJyALQgWkOYFxOlEdwS04VDmBj2FfpnBasa8g4oW0SWCpHBeTw/1iAbb3Q8QKBgQDr4lkj8LIYoIIoZ80BlQNdTlcTRoo3lo1Iq8QE6e8ufQ6ipItcCDS40qSoe93HxD7z7Lo1/68JunE1F6jsXkgMcLEN5VrMCdRZPeytdSX3TN1KjhgSWS44NU3B1zoU1j3EAdtz6Meaz/NBStH9Dj34VN8IHHqbRcYXifXhzXvl4QKBgEOKqFKKyzBbYEEo6KqXdLc4vJJYQOkA79l5gm17AxEjBv3pLrYuqqxS1cYnR7BmO3bbmQGxiWCyqR7+8EzLOGwTVAizR9b7pE1ZHusIERtJ8FZcrYopXFNvtLee+9DsHx9Wmm3vScaK7ae+LCkGdOcew67+ljZFdeTdgPIPZyZRAoGBAONz60wfukdZsvEEBzYllYEqSakhMvbZTb3ga4Zg3SqbcggUxGkjM8q8I3OCw3mLqeSL+yAKFCEE/o58JpltHJFp64/PtcejjgGFB7NThxi2grw+Us5vu239iajJMAaWsyW8qRMynn1GS6+i6Vibetih7Rw1b6nmawOov5J/XqiK";
    public static final String RSA_PRIVATE = "";

//    MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCJfRln0g06MVNJcYR5ilaAJpNcPW3+lpEv3F7f/VZBBu03DSzvXVD2Elq60B2NlZa9PJ5dj+rETWfuA9b0JTYCXrJ6Fwddbn8tUDInha91LeD39xGSnGuRo3N5UKMeBHx8yi/QDl2LfxM0Bm713uQkvqAlOH9EIVKc4PjCvHS17v6z32HNYnomy8vFSIDkK/ZxGyZaaFhKPa9SwyRW/MkTeBU2KE09xOrFf9ignyPT6VOj7/ufda5as5vpwY+PohPPzZk/V0bmu6P0SEZhHliWbD7mY+y0s2sRnFPDqzXnjEdWaq/COL0JOw1Jitwc6b4fe5ucV4Ct+z6fa4mt758tAgMBAAECggEAVbLGbTI+0HECaxr46hFSjZp969bWgwQzB1QjRxbP9sRshA4QXjsaRed26k7ivOfrB5WLWOJmAWoGSBPYnmG7YorIUNWd350KZKJCQORRU4b/XVCBgZNCcYsiZRHgOsutFNOqLdNmd5cDzz/bViJSrpyrkce/fCYRKnwIUsnJLcUawKTQ8sg74eh4pZadehaIRdsHSghpyPLt+kAyUFC1gZ5AXpyEOI6vNIw6alCpTHAkaWDfIqETzdVgA+ldfrJv0+z20AmbujPFbWtu61GWPYxij+CA30QKpprrRkEJiWNsjhgelnQdwaKZF6TPR/0pWM2doGw+tuhSybAi8rDC+QKBgQDA86oDNFrO6+jm/t4S8vKKOUiKkzKUoNyHU7GAm037vOM52a5J7d6hS5+ofh070CJeoVr3YfKEVWFVeHVJJwBL1DtRFt0dyjklCivCDW4Vh18ZeoaBcF32eIwc69ggWVQ6ycSWPvMMrYa9brDo4MN/1vOpZrefPDGUS3709K4HYwKBgQC2afeRj+kbjkh2hB4Htp3qVE20+gku51Q0Aj0j783MiLSBI3fNQp7oyKDWPW9/LSRKN4ddO348VtulIFWakmUAjq/Bo/5nmvo+omnY8xA47+BQBYiPupIUz8aEXnJWk9ctPX6aESLk5qANkBa1ICvmb2RSoXPRVN24moU8qC/sLwKBgBdGzcGpNTM1HlmPcXbTvBKUqn2dGEL5zOC+ZfFfyt6NgNPfwLjGa08F8nK/FAO9LghAatrhBAKW0jEfYPa8L7r2FVnI6k/Hr3EacwDr4dXTCNPoBgXjalJrZGuwv9fXLuQQpxiA640h+dksW0ccpjjr02UiMRCSkGCVYvFl+wCFAoGBAKOGpYBhcYjZaY6Na9pgVHqgLrVBvP/GM08YfrT7ohNsrdxi7mAdDBYE3WKR2qU406KQ2xGyZr0y5F7IeNVDzbXNNDQ0jrlUTmfd82OgqndQW1eBTmYCzDhJ913syTVh/XE6AoedOxnWwb7G4ARpndFLJLWKtSgAm2+FXlH9OFDTAoGAIPM56oigVAr8gCWREtwIZi36n9Wll3SUDrdtpxoI/J3TAxTrzLnprJx2PyaB0oGHR3ZUw6zM8CGd7+5qNTb7bLX3Wv7WUbtXtvmcu0KG82NnxdJwWFU957RMRiyw/dUrqnBoqxoKfJS62gGH4/h7w175OfrFoRRJGa+LZKFpi6c=

    private static final int SDK_PAY_FLAG = 1;
    private static final int SDK_AUTH_FLAG = 2;

    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler() {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case SDK_PAY_FLAG: {
                    @SuppressWarnings("unchecked")
                    PayResult payResult = new PayResult((Map<String, String>) msg.obj);
                    /**
                     * 对于支付结果，请商户依赖服务端的异步通知结果。同步通知结果，仅作为支付结束的通知。
                     */
                    String resultInfo = payResult.getResult();// 同步返回需要验证的信息
                    String resultStatus = payResult.getResultStatus();
                    // 判断resultStatus 为9000则代表支付成功
                    if (TextUtils.equals(resultStatus, "9000")) {
                        // 该笔订单是否真实支付成功，需要依赖服务端的异步通知。
                        showAlert(PayDemoActivity.this, getString(com.henghai.zhenxuan.R.string.pay_success) + payResult);
                    } else {
                        // 该笔订单真实的支付结果，需要依赖服务端的异步通知。
                        showAlert(PayDemoActivity.this, getString(R.string.pay_failed) + payResult);
                    }
                    break;
                }
                case SDK_AUTH_FLAG: {
                    @SuppressWarnings("unchecked")
                    AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);
                    String resultStatus = authResult.getResultStatus();

                    // 判断resultStatus 为“9000”且result_code
                    // 为“200”则代表授权成功，具体状态码代表含义可参考授权接口文档
                    if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {
                        // 获取alipay_open_id，调支付时作为参数extern_token 的value
                        // 传入，则支付账户为该授权账户
                        showAlert(PayDemoActivity.this, getString(R.string.auth_success) + authResult);
                    } else {
                        // 其他状态值则为授权失败
                        showAlert(PayDemoActivity.this, getString(R.string.auth_failed) + authResult);
                    }
                    break;
                }
                default:
                    break;
            }
        }

        ;
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_main);
    }

    /**
     * 支付宝支付业务示例
     */
    public void payV2(View v) {
        if (TextUtils.isEmpty(APPID) || (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))) {
            showAlert(this, getString(R.string.error_missing_appid_rsa_private));
            return;
        }

        /*
         * 这里只是为了方便直接向商户展示支付宝的整个支付流程；所以Demo中加签过程直接放在客户端完成；
         * 真实App里，privateKey等数据严禁放在客户端，加签过程务必要放在服务端完成；
         * 防止商户私密数据泄露，造成不必要的资金损失，及面临各种安全风险；
         *
         * orderInfo 的获取必须来自服务端；
         */
        boolean rsa2 = (RSA2_PRIVATE.length() > 0);
        Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2, null);
        String orderParam = OrderInfoUtil2_0.buildOrderParam(params);

        String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
        String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);
        final String orderInfo = orderParam + "&" + sign;

        final Runnable payRunnable = new Runnable() {

            @Override
            public void run() {
                PayTask alipay = new PayTask(PayDemoActivity.this);
                Map<String, String> result = alipay.payV2(orderInfo, true);
                Log.i("msp", result.toString());

                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

        // 必须异步调用
        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }

    /**
     * 支付宝账户授权业务示例
     */
    public void authV2(View v) {
        if (TextUtils.isEmpty(PID) || TextUtils.isEmpty(APPID)
                || (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))
                || TextUtils.isEmpty(TARGET_ID)) {
            showAlert(this, getString(R.string.error_auth_missing_partner_appid_rsa_private_target_id));
            return;
        }

        /*
         * 这里只是为了方便直接向商户展示支付宝的整个支付流程；所以Demo中加签过程直接放在客户端完成；
         * 真实App里，privateKey等数据严禁放在客户端，加签过程务必要放在服务端完成；
         * 防止商户私密数据泄露，造成不必要的资金损失，及面临各种安全风险；
         *
         * authInfo 的获取必须来自服务端；
         */
        boolean rsa2 = (RSA2_PRIVATE.length() > 0);
        Map<String, String> authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap(PID, APPID, TARGET_ID, rsa2);
        String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);

        String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;
        String sign = OrderInfoUtil2_0.getSign(authInfoMap, privateKey, rsa2);
        final String authInfo = info + "&" + sign;
        Runnable authRunnable = new Runnable() {

            @Override
            public void run() {
                // 构造AuthTask 对象
                AuthTask authTask = new AuthTask(PayDemoActivity.this);
                // 调用授权接口，获取授权结果
                Map<String, String> result = authTask.authV2(authInfo, true);

                Message msg = new Message();
                msg.what = SDK_AUTH_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

        // 必须异步调用
        Thread authThread = new Thread(authRunnable);
        authThread.start();
    }

    /**
     * 获取支付宝 SDK 版本号。
     */
    public void showSdkVersion(View v) {
        PayTask payTask = new PayTask(this);
        String version = payTask.getVersion();
        showAlert(this, getString(R.string.alipay_sdk_version_is) + version);
    }

    /**
     * 将 H5 网页版支付转换成支付宝 App 支付的示例
     */
    public void h5Pay(View v) {
        WebView.setWebContentsDebuggingEnabled(true);
        Intent intent = new Intent(this, H5PayDemoActivity.class);
        Bundle extras = new Bundle();

        /*
         * URL 是要测试的网站，在 Demo App 中会使用 H5PayDemoActivity 内的 WebView 打开。
         *
         * 可以填写任一支持支付宝支付的网站（如淘宝或一号店），在网站中下订单并唤起支付宝；
         * 或者直接填写由支付宝文档提供的“网站 Demo”生成的订单地址
         * （如 https://mclient.alipay.com/h5Continue.htm?h5_route_token=303ff0894cd4dccf591b089761dexxxx）
         * 进行测试。
         *
         * H5PayDemoActivity 中的 MyWebViewClient.shouldOverrideUrlLoading() 实现了拦截 URL 唤起支付宝，
         * 可以参考它实现自定义的 URL 拦截逻辑。
         *
         * 注意：WebView 的 shouldOverrideUrlLoading(url) 无法拦截直接调用 open(url) 打开的第一个 url，
         * 所以直接设置 url = "https://mclient.alipay.com/cashier/mobilepay.htm......" 是无法完成网页转 Native 的。
         * 如果需要拦截直接打开的支付宝网页支付 URL，可改为使用 shouldInterceptRequest(view, request) 。
         */
        String url = "https://m.taobao.com";
        extras.putString("url", url);
        intent.putExtras(extras);
        startActivity(intent);
    }

    private static void showAlert(Context ctx, String info) {
        showAlert(ctx, info, null);
    }

    private static void showAlert(Context ctx, String info, DialogInterface.OnDismissListener onDismiss) {
        new AlertDialog.Builder(ctx)
                .setMessage(info)
                .setPositiveButton(R.string.confirm, null)
                .setOnDismissListener(onDismiss)
                .show();
    }

    private static void showToast(Context ctx, String msg) {
        Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();
    }

    private static String bundleToString(Bundle bundle) {
        if (bundle == null) {
            return "null";
        }
        final StringBuilder sb = new StringBuilder();
        for (String key : bundle.keySet()) {
            sb.append(key).append("=>").append(bundle.get(key)).append("\n");
        }
        return sb.toString();
    }
}
